#ifndef CTTGIPSCONNECTOR_H
#define CTTGIPSCONNECTOR_H

#include <QObject>
#include <QThread>
#include <QHostAddress>
#include <QUdpSocket>
#include <QTimer>
#include <QFile>
#include <QReadWriteLock>
#include "define_cmd.h"
#include "knx/qt_knx.h"

class CIpsHeartBreakThread : public QThread
{
    Q_OBJECT
public:
    explicit CIpsHeartBreakThread(QThread *parent = 0);
    int _heartbeatState;
    bool run_state;

signals:
    void s_sendHeartBreak();
    void s_heartBreakState(int);

protected:
    void run();
    int is_connect_lost();
};

class CIpsWriteStruct
{
public:
    explicit CIpsWriteStruct(){}
    QByteArray addr2bytes;
    int data_type;
    QByteArray data;
};

class CTTGIpsConnector : public QObject
{
    Q_OBJECT
public:
    explicit CTTGIpsConnector(QObject *parent = 0);

    bool usingSocket;
    bool runningState();

    void setNetWork(QString ip,int port);
    void setLogInfo(QString username,QString password);
    void startConnect();
    void disConnect();

    _int32 ttg_read_status(_u8 addr[2]);
    _int32 ttg_write_device(_u8 addr[2], _u8 value_type, _u8 *data, _u32 len);

    _int32 ttg_disconnect();
    _int32 ttg_connect_state(_u8 *buff);

    bool registeObject(void *devObj,void *userdata);
    bool unRegisterObject(void *devObj,void *userdata);
    void unRegisterAll();

    void removeReadCheck(QByteArray addr);
    void removeWriteCheck(QByteArray addr);

protected:

    void set_package_length(char *buff_head,short length);
    void encry_knx_data(unsigned char random,char *knx, unsigned int size,char *encry_buf);
    void generate_encry_password(char *pass,char encry_pass[7]);
    void ttg_set_pass(char *user,char *pass);
    unsigned int set_msg_header(char *buff);

    _u8 calc_crc_from_control1_BC(_u8 *buff,_u8 size);
    _u8 package_cmei_msg_ttg(_u8 msg[],_u8 controlField1,_u8 addr[2],_u8 *value,_u8 size);
    int ttg_send_msg(char *buff,int size);

    void ttg_data_unpackage(_u8 *cemi_data,int size,_u8 *decode_buf);
    bool ttg_data_crc_verify(_u8 *data,int size);
    unsigned short ttg_data_package(_u8 addr[2],_u8 *value,char value_len,_u8 *buff);
    void data_analyze(QByteArray bytes,QString peerIP,unsigned short peerPort);

    void ttg_heart_beat_recv_msg(_int32 status_code);

    _int32 ttg_cmei_data_analyze(_u8 msg[],_u8 msg_len);
    _int32 ttg_data_analyze(_u8 msg[],_u8 msg_len);
    _int32 message_device_data_handle(DEVICE_OBJECT *data,_u8 *value,_u8 value_len);
    _int32 routing_indication_recv_analyze(_u8 data[],_u32 data_type,_u8 *operation_type,
                                           _u8 **ret_value,_u8 *ret_len);

signals:
    void s_gateWayConnectState(int state);
    void s_valueNotify(void *devObj,QByteArray value,void *userdata);

public slots:
    void readDataSocket();
    void heartBreak();
    void heartBreakCheck(int state);
    void doReadDevice(QByteArray addr2bytes);
    void doWriteDevice(QByteArray addr2bytes,int data_type,QByteArray data);
    void doRegistObject(void *dev,void *userdata);
    void doReadCheck();
    void doWriteCheck();

private:
    QReadWriteLock lock;
    QUdpSocket *udp;
    QFile _knxSendChannel,_knxRcvChannel;
    QHostAddress serverAddr;
    int serverPort;

    int _gateWayState;
    CIpsHeartBreakThread _hearThread;

    QList<QByteArray> _readList;
    QList<CIpsWriteStruct> _writeList;
    QTimer _readCheckTimer, _writeCheckTimer;
    QMultiMap<QByteArray, DEVICE_OBJECT *> _registersMap;
};

#endif // CTTGIPSCONNECTOR_H
